/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "Vk图像.h"


S_键值序列容器<uint32, S_VkImage*> g_场景容器;




void f_releaseImage(VkDevice dev, S_VkImage* obj) {
	if (obj->m_Mem) {
		vkDestroyImageView(dev, obj->m_View, NULL);
		vkDestroyImage(dev, obj->m_Image, NULL);
		vkFreeMemory(dev, obj->m_Mem, NULL);
	}
}


inline VkMemoryRequirements f_get图像内存配置(const VkDevice& dev, const VkImage& i) {
	VkMemoryRequirements mem_reqs;
	vkGetImageMemoryRequirements(dev, i, &mem_reqs);
	return mem_reqs;
}


inline VkImageType f_转VK纹理类型(E_纹理维度类型 type) {
	switch (type) {
	case e_1D: return VK_IMAGE_TYPE_1D;
	case e_2D: return VK_IMAGE_TYPE_2D;
	case e_3D: return VK_IMAGE_TYPE_3D;
	case e_2D_Array: return VK_IMAGE_TYPE_2D;
	default:
		break;
	}

	return VK_IMAGE_TYPE_2D;
}
inline VkImageViewType f_转VK纹理视图类型(E_纹理维度类型 type) {
	switch (type) {
	case e_1D: return VK_IMAGE_VIEW_TYPE_1D;
	case e_2D: return VK_IMAGE_VIEW_TYPE_2D;
	case e_3D: return VK_IMAGE_VIEW_TYPE_3D;
	case e_2D_Array: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
	case e_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE;
	case e_CUBE_Array: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
	default:
		break;
	}
	return VK_IMAGE_VIEW_TYPE_2D;
}


inline VkSamplerAddressMode f_转VK纹理拉伸方式(E_纹理拉伸方式 方式) {
	switch (方式)
	{
	case e_重复:		return VK_SAMPLER_ADDRESS_MODE_REPEAT;
	case e_镜像重复:	return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
	case e_边缘:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
	case e_镜像边缘:	return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
	case e_边框:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
		break;
	default:
		break;
	}
	return VK_SAMPLER_ADDRESS_MODE_REPEAT;
}


/*VkImageUsageFlags f_get纹理用途(E_纹理用途 用途) {
	switch (用途)
	{
	case e_采样:			return VK_IMAGE_USAGE_SAMPLED_BIT;
	case e_暂存附件:		return VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
	case e_颜色附件:		return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
	case e_深度模板附件:	return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
	case e_存储:			return VK_IMAGE_USAGE_STORAGE_BIT;
	case e_暂存源:			return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	case e_暂存目标:		return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	case e_输入附件:		return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
	case e_SHADING_RATE:			return VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV;
	case e_FRAGMENT_DENSITY_MAP:	return VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT;
	default:
		break;
	}

	return VK_IMAGE_USAGE_SAMPLED_BIT;
}*/


//VkImageAspectFlagBits


S_Vk图像管理::~S_Vk图像管理() {
	
}

void S_Vk图像管理::f_释放图像(VkDevice& dev, S_VkImage* image) {
	uint32 key = image->m_ID;
	if (g_场景容器.f_Key存在(key)) {
		auto t = g_场景容器[key];

		f_releaseImage(dev, t);
		free(t);

		g_场景容器.f_remove(key);

	} else if(image != NULL) {
		for (auto& t : g_场景容器.gData序列容器) {
			f_releaseImage(dev, t);
			free(t);
		}
	}
	
	//delete image;
}

S_VkImage* S_Vk图像管理::f_创建图像视图(VkDevice& dev, VkImage image, const VkFormat& 格式, uint32 key) {
	S_VkImage* obj = (S_VkImage*)malloc(sizeof(S_VkImage));

	obj->m_Mem = 0;
	obj->m_View = 0;
	obj->m_Image = image;


	VkImageViewCreateInfo 图像视口创建信息 = {};
	图像视口创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
	图像视口创建信息.pNext = NULL;
	图像视口创建信息.image = image;
	图像视口创建信息.format = 格式;
	图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
	图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_G;
	图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_B;
	图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_A;
	图像视口创建信息.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
	图像视口创建信息.subresourceRange.baseMipLevel = 0;
	图像视口创建信息.subresourceRange.levelCount = 1;
	图像视口创建信息.subresourceRange.baseArrayLayer = 0;
	图像视口创建信息.subresourceRange.layerCount = 1;
	图像视口创建信息.viewType = VK_IMAGE_VIEW_TYPE_2D;
	图像视口创建信息.flags = 0;
	
	

	VkResult res = vkCreateImageView(dev, &图像视口创建信息, NULL, &obj->m_View);
	assert(res == VK_SUCCESS);

	key = g_场景容器.f_GenName(key);
	g_场景容器.f_add(obj, key);
	obj->m_ID = key;

	return obj;
}

S_VkImage* S_Vk图像管理::f_创建纹理图像(S_绘图设备配置& 配置, const VkFormat& 格式, uvec3 size, E_纹理维度类型 类型, uint32 用途, E_MS次数 采样, uint32 key) {
	S_VkImage* obj = new S_VkImage();
	S_VkImage& iObj = *obj;

	VkResult res;
	VkImageCreateInfo 图像创建信息 = {};
	图像创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
	图像创建信息.pNext = NULL;
	图像创建信息.imageType = f_转VK纹理类型(类型);
	图像创建信息.format = 格式; 
	图像创建信息.extent.width = size.x;
	图像创建信息.extent.height = size.y;
	图像创建信息.extent.depth = 1;
	图像创建信息.mipLevels = 1;
	图像创建信息.arrayLayers = size.z;
	图像创建信息.samples = f_get多重采样Bits(采样);
	图像创建信息.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
	//图像创建信息.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
	图像创建信息.usage = 用途;
	图像创建信息.queueFamilyIndexCount = 0;
	图像创建信息.pQueueFamilyIndices = 0;
	图像创建信息.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
	图像创建信息.flags = 0;
	//VK_IMAGE_TILING_LINEAR: 纹素基于行主序的布局，如pixels数组
	//VK_IMAGE_TILING_OPTIMAL : 纹素基于具体的实现来定义布局，以实现最佳访问
	//如果需要在内存图像中直接访问纹素，必须使用VK_IMAGE_TILING_LINEAR
	图像创建信息.tiling = VK_IMAGE_TILING_OPTIMAL;
	//图像创建信息.tiling;

	res = vkCreateImage(配置.m_设备, &图像创建信息, NULL, &iObj.m_Image);
	assert(res == VK_SUCCESS);




	auto 内存配置 = f_get图像内存配置(配置.m_设备, iObj.m_Image);
	VkMemoryAllocateInfo 内存分配信息 = {};
	内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	内存分配信息.pNext = NULL;
	内存分配信息.allocationSize = 内存配置.size;
	内存分配信息.memoryTypeIndex = f_内存类型索引(配置.m_内存属性, 内存配置.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

	res = vkAllocateMemory(配置.m_设备, &内存分配信息, NULL, &iObj.m_Mem);
	assert(res == VK_SUCCESS);
	res = vkBindImageMemory(配置.m_设备, iObj.m_Image, iObj.m_Mem, 0);
	assert(res == VK_SUCCESS);




	VkImageViewCreateInfo 图像视口创建信息 = {};
	图像视口创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
	图像视口创建信息.pNext = NULL;

	图像视口创建信息.format = 格式;
	switch (格式) {
	case VK_FORMAT_R8_UNORM:
	case VK_FORMAT_R8_SNORM:
	case VK_FORMAT_R8_USCALED:
	case VK_FORMAT_R8_SSCALED:
	case VK_FORMAT_R8_UINT:
	case VK_FORMAT_R8_SINT:
	case VK_FORMAT_R8_SRGB:
		图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
		图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_R;
		图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_R;
		图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_R;
		break;
	default:
		图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
		图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_G;
		图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_B;
		图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_A;
		break;
	}
	
	图像视口创建信息.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
	图像视口创建信息.subresourceRange.baseMipLevel = 0;
	图像视口创建信息.subresourceRange.levelCount = 1;
	图像视口创建信息.subresourceRange.baseArrayLayer = 0;
	图像视口创建信息.subresourceRange.layerCount = size.z;
	图像视口创建信息.viewType = f_转VK纹理视图类型(类型);
	图像视口创建信息.flags = 0;
	图像视口创建信息.image = iObj.m_Image;


	res = vkCreateImageView(配置.m_设备, &图像视口创建信息, NULL, &iObj.m_View);
	assert(res == VK_SUCCESS);


	iObj.m_布局 = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
	iObj.m_着色器参数.imageLayout = iObj.m_布局;
	iObj.m_着色器参数.imageView = iObj.m_View;
	iObj.m_着色器参数.sampler;

	key = g_场景容器.f_GenName(key);
	g_场景容器.f_add(obj, key);
	obj->m_ID = key;



	return obj;
}

S_VkImage* S_Vk图像管理::f_创建帧缓存图像(VkDevice& dev, VkPhysicalDeviceMemoryProperties 内存属性, const VkFormat& 格式, uvec3 size, E_MS次数 采样, uint32 用途) {
	//S_VkImage* obj = (S_VkImage*)malloc(sizeof(S_VkImage));
	S_VkImage* obj = new S_VkImage;
	S_VkImage& iObj = *obj;
	iObj.m_采样 = 采样;

	VkResult res;

	VkImageCreateInfo 图像创建信息 = {};
	图像创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
	图像创建信息.pNext = NULL;
	图像创建信息.imageType = VK_IMAGE_TYPE_2D;
	图像创建信息.format = 格式;
	图像创建信息.extent.width = size.x;
	图像创建信息.extent.height = size.y;
	图像创建信息.extent.depth = 1;
	图像创建信息.mipLevels = 1;
	图像创建信息.arrayLayers = size.z;
	图像创建信息.samples = f_get多重采样Bits(采样);
	图像创建信息.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
	图像创建信息.usage = 用途;
	图像创建信息.queueFamilyIndexCount = 0;
	图像创建信息.pQueueFamilyIndices = 0;
	图像创建信息.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
	图像创建信息.flags = 0;
	

	//VK_IMAGE_TILING_LINEAR: 纹素基于行主序的布局，如pixels数组
	//VK_IMAGE_TILING_OPTIMAL : 纹素基于具体的实现来定义布局，以实现最佳访问
	//如果需要在内存图像中直接访问纹素，必须使用VK_IMAGE_TILING_LINEAR

	//图像创建信息.tiling = VK_IMAGE_TILING_OPTIMAL;
	图像创建信息.tiling = VK_IMAGE_TILING_OPTIMAL;

	res = vkCreateImage(dev, &图像创建信息, NULL, &iObj.m_Image);
	assert(res == VK_SUCCESS);



	auto 内存配置 = f_get图像内存配置(dev, iObj.m_Image);
	VkMemoryAllocateInfo 内存分配信息 = {};
	内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	内存分配信息.pNext = NULL;
	内存分配信息.allocationSize = 内存配置.size;
	内存分配信息.memoryTypeIndex = f_内存类型索引(内存属性, 内存配置.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
	

	uint8 分配内存次数 = 0;
	To_重新分配内存:
	res = vkAllocateMemory(dev, &内存分配信息, NULL, &iObj.m_Mem);
	if (res != VK_SUCCESS) {
		//_sleep(100);
		Sleep(100);
		if (分配内存次数 < 10) {
			++分配内存次数;
			goto To_重新分配内存;
		}
	}
	assert(res == VK_SUCCESS);

	res = vkBindImageMemory(dev, iObj.m_Image, iObj.m_Mem, 0);
	assert(res == VK_SUCCESS);



	VkImageViewCreateInfo 图像视口创建信息 = {};
	图像视口创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
	图像视口创建信息.pNext = NULL;

	图像视口创建信息.format = 格式;
	图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
	图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_G;
	图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_B;
	图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_A;
	图像视口创建信息.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
	图像视口创建信息.subresourceRange.baseMipLevel = 0;
	图像视口创建信息.subresourceRange.levelCount = 1;
	图像视口创建信息.subresourceRange.baseArrayLayer = 0;
	图像视口创建信息.subresourceRange.layerCount = size.z;
	图像视口创建信息.viewType = VK_IMAGE_VIEW_TYPE_2D;
	图像视口创建信息.flags = 0;
	图像视口创建信息.image = iObj.m_Image;
	




	res = vkCreateImageView(dev, &图像视口创建信息, NULL, &iObj.m_View);
	assert(res == VK_SUCCESS);

	iObj.m_布局 = VK_IMAGE_LAYOUT_GENERAL;
	iObj.m_着色器参数.imageLayout = VK_IMAGE_LAYOUT_GENERAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
	//iObj.m_着色器参数.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
	//iObj.m_着色器参数.imageLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
	iObj.m_着色器参数.imageView = iObj.m_View;
	iObj.m_着色器参数.sampler;


	uint32 key = 0;
	key = g_场景容器.f_GenName(key);
	g_场景容器.f_add(obj, key);
	obj->m_ID = key;


	return obj;
}

S_VkImage * S_Vk图像管理::f_创建深度缓存图像(VkDevice& dev, VkPhysicalDeviceMemoryProperties 内存属性, VkPhysicalDeviceProperties 物理设备属性, VkFormat 图像格式, uvec3 size, E_MS次数 采样, uint32 key) {
	//S_VkImage* obj = (S_VkImage*)malloc(sizeof(S_VkImage));
	S_VkImage* obj = new S_VkImage;

	S_VkImage& iObj = *obj;
	iObj.m_采样 = 采样;

	VkResult res;
	VkImageCreateInfo 图像创建信息 = {};
	图像创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
	图像创建信息.pNext = NULL;
	图像创建信息.imageType = VK_IMAGE_TYPE_2D;
	图像创建信息.format = 图像格式;
	图像创建信息.extent.width = size.x;
	图像创建信息.extent.height = size.y;
	图像创建信息.extent.depth = 1;
	图像创建信息.mipLevels = 1;
	图像创建信息.arrayLayers = size.z;
	图像创建信息.samples = f_get多重采样Bits(采样);
	图像创建信息.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
	图像创建信息.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
	图像创建信息.queueFamilyIndexCount = 0;
	图像创建信息.pQueueFamilyIndices = 0;
	图像创建信息.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
	图像创建信息.flags = 0;

	vkCreateImage(dev, &图像创建信息, NULL, &iObj.m_Image);

	auto 内存配置 = f_get图像内存配置(dev, iObj.m_Image);
	VkMemoryAllocateInfo 内存分配信息 = {};
	内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	内存分配信息.pNext = NULL;
	内存分配信息.allocationSize = 内存配置.size;
	内存分配信息.memoryTypeIndex = f_内存类型索引(内存属性, 内存配置.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
	//f_内存类型_from_properties();
	res = vkAllocateMemory(dev, &内存分配信息, NULL, &iObj.m_Mem);
	assert(res == VK_SUCCESS);

	res = vkBindImageMemory(dev, iObj.m_Image, iObj.m_Mem, 0);
	assert(res == VK_SUCCESS);


	VkImageViewCreateInfo 图像视口创建信息 = {};
	图像视口创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
	图像视口创建信息.pNext = NULL;
	
	图像视口创建信息.format = 图像格式;
	//图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
	//图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_G;
	//图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_B;
	//图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_A;
	图像视口创建信息.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
	图像视口创建信息.subresourceRange.baseMipLevel = 0;
	图像视口创建信息.subresourceRange.levelCount = 1;
	图像视口创建信息.subresourceRange.baseArrayLayer = 0;
	图像视口创建信息.subresourceRange.layerCount = 1;
	图像视口创建信息.viewType = VK_IMAGE_VIEW_TYPE_2D;
	图像视口创建信息.flags = 0;
	图像视口创建信息.image = iObj.m_Image;


	
	res = vkCreateImageView(dev, &图像视口创建信息, NULL, &iObj.m_View);
	assert(res == VK_SUCCESS);

	key = g_场景容器.f_GenName(key);
	g_场景容器.f_add(obj, key);
	obj->m_ID = key;

	return obj;
}






VkFormat findSupportedFormat(	const VkPhysicalDevice phyDev, 
								const vector<VkFormat>& candidates, 
								VkImageTiling tiling, 
								VkFormatFeatureFlags features)
{
	for (VkFormat format : candidates) {
		VkFormatProperties props;
		vkGetPhysicalDeviceFormatProperties(phyDev, format, &props);

		//是否支持瓦片组织方式
		if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) {
			return format;
		}
		//是否支持最优瓦片组织方式
		else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) {
			return format;
		}
	}

	throw std::runtime_error("查找图像格式失败");
}

VkFormat f_findDepthFormat(const VkPhysicalDevice phyDev) {
	return findSupportedFormat(phyDev,
		{ VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM },
		VK_IMAGE_TILING_OPTIMAL,																					//是否支持瓦片组织方式
		VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT																//是否支持最优瓦片组织方式
	);
}










void f_VkImage_构建(S_VkImage* obj, S_设备环境& ctx) {
	VkDevice		逻辑设备	= (VkDevice)(ctx.m_逻辑设备.设备);
	S_物理设备属性* prop		= (S_物理设备属性*)ctx.m_物理设备.pNext;
	
	//static std::mutex g分配内存锁;
	//g分配内存锁.lock();

	f_releaseImage(逻辑设备, obj);

	VkResult res;
	VkImageCreateInfo 图像创建信息 = {};
	图像创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
	图像创建信息.pNext = NULL;
	图像创建信息.imageType = f_转VK纹理类型(obj->m_类型);
	图像创建信息.format = f_转VK图像格式(obj->m_格式);
	图像创建信息.extent.width = obj->m_Size.x;
	图像创建信息.extent.height = obj->m_Size.y;
	图像创建信息.extent.depth = 1;
	图像创建信息.mipLevels = 1;
	图像创建信息.arrayLayers = obj->m_Size.z;
	图像创建信息.samples = f_get多重采样Bits(obj->m_采样);
	图像创建信息.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
	//图像创建信息.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
	图像创建信息.usage = obj->m_用途;
	图像创建信息.queueFamilyIndexCount = 0;
	图像创建信息.pQueueFamilyIndices = 0;
	图像创建信息.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
	图像创建信息.flags = 0;

	//VK_IMAGE_TILING_LINEAR: 纹素基于行主序的布局，如pixels数组
	//VK_IMAGE_TILING_OPTIMAL : 纹素基于具体的实现来定义布局，以实现最佳访问
	//如果需要在内存图像中直接访问，必须使用VK_IMAGE_TILING_LINEAR
	图像创建信息.tiling = VK_IMAGE_TILING_OPTIMAL;
	//图像创建信息.tiling;

	res = vkCreateImage(逻辑设备, &图像创建信息, NULL, &(obj->m_Image));
	assert(res == VK_SUCCESS);


	auto 内存配置 = f_get图像内存配置(逻辑设备, obj->m_Image);
	VkMemoryAllocateInfo 内存分配信息 = {};
	内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	内存分配信息.pNext = NULL;
	内存分配信息.allocationSize = 内存配置.size;
	内存分配信息.memoryTypeIndex = f_内存类型索引(prop->m_内存属性, 内存配置.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);


	res = vkAllocateMemory(逻辑设备, &内存分配信息, NULL, &(obj->m_Mem));
	assert(res == VK_SUCCESS);
	res = vkBindImageMemory(逻辑设备, obj->m_Image, obj->m_Mem, 0);
	assert(res == VK_SUCCESS);



	VkImageViewCreateInfo 图像视口创建信息 = {};
	图像视口创建信息.sType	= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
	图像视口创建信息.pNext	= NULL;
	图像视口创建信息.format	= f_转VK图像格式(obj->m_格式);
	/*switch (obj->m_格式) {
	case VK_FORMAT_R8_UNORM:
	case VK_FORMAT_R8_SNORM:
	case VK_FORMAT_R8_USCALED:
	case VK_FORMAT_R8_SSCALED:
	case VK_FORMAT_R8_UINT:
	case VK_FORMAT_R8_SINT:
	case VK_FORMAT_R8_SRGB:
		图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
		图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_R;
		图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_R;
		图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_R;
		break;
	default:
		图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
		图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_G;
		图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_B;
		图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_A;
		break;
	}*/

	图像视口创建信息.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
	图像视口创建信息.subresourceRange.baseMipLevel = 0;
	图像视口创建信息.subresourceRange.levelCount = 1;
	图像视口创建信息.subresourceRange.baseArrayLayer = 0;
	图像视口创建信息.subresourceRange.layerCount = obj->m_Size.z;
	图像视口创建信息.viewType = f_转VK纹理视图类型(obj->m_类型);
	图像视口创建信息.flags = 0;
	图像视口创建信息.image = obj->m_Image;


	res = vkCreateImageView(逻辑设备, &图像视口创建信息, NULL, &(obj->m_View));
	assert(res == VK_SUCCESS);


	obj->m_着色器参数.imageLayout = obj->m_布局;
	obj->m_着色器参数.imageView = obj->m_View;
	obj->m_着色器参数.sampler = obj->m_着色器参数.sampler;

	//g分配内存锁.unlock();
}


VkImageMemoryBarrier f_vk_图像屏障() {
	VkImageMemoryBarrier imageMemoryBarrier{};
	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	return imageMemoryBarrier;
}









S_Vk纹理采样器::S_Vk纹理采样器(VkDevice& dev, S_纹理采样器创建参数 参数) {
	VkSamplerCreateInfo info = {};

	info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
	info.magFilter = VK_FILTER_LINEAR;
	info.minFilter = VK_FILTER_NEAREST;
	info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
	info.addressModeU = f_转VK纹理拉伸方式(参数.U);
	info.addressModeV = f_转VK纹理拉伸方式(参数.V);
	info.addressModeW = f_转VK纹理拉伸方式(参数.W);
	info.minLod = 0.0;
	info.maxLod = 0.5;
	info.mipLodBias = 0;

	info.anisotropyEnable = true;
	info.maxAnisotropy = 1;
	info.compareEnable = false;
	info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;

	vkCreateSampler(dev, &info, 0, &m_采样器);

}
